<template>
  <div class="app-container">
    <canvas id="c"></canvas>

    <div id="content">
      <div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - multiple elements - webgl</div>
    </div>
  </div>
</template>
<script>
  import * as THREE from 'three'

  export default {
    data() {
      return {
        canvas: null,
        scenes: [],
        renderer: null
      }
    },
    created() {
      // this.init()
      /*THREE.OrbitControls = function ( object, domElement ) {

        this.object = object;

        this.domElement = ( domElement !== undefined ) ? domElement : document;

        // Set to false to disable this control
        this.enabled = true;

        // "target" sets the location of focus, where the object orbits around
        this.target = new THREE.Vector3();

        // How far you can dolly in and out ( PerspectiveCamera only )
        this.minDistance = 0;
        this.maxDistance = Infinity;

        // How far you can zoom in and out ( OrthographicCamera only )
        this.minZoom = 0;
        this.maxZoom = Infinity;

        // How far you can orbit vertically, upper and lower limits.
        // Range is 0 to Math.PI radians.
        this.minPolarAngle = 0; // radians
        this.maxPolarAngle = Math.PI; // radians

        // How far you can orbit horizontally, upper and lower limits.
        // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
        this.minAzimuthAngle = - Infinity; // radians
        this.maxAzimuthAngle = Infinity; // radians

        // Set to true to enable damping (inertia)
        // If damping is enabled, you must call controls.update() in your animation loop
        this.enableDamping = false;
        this.dampingFactor = 0.25;

        // This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
        // Set to false to disable zooming
        this.enableZoom = true;
        this.zoomSpeed = 1.0;

        // Set to false to disable rotating
        this.enableRotate = true;
        this.rotateSpeed = 1.0;

        // Set to false to disable panning
        this.enablePan = true;
        this.panSpeed = 1.0;
        this.screenSpacePanning = false; // if true, pan in screen-space
        this.keyPanSpeed = 7.0;	// pixels moved per arrow key push

        // Set to true to automatically rotate around the target
        // If auto-rotate is enabled, you must call controls.update() in your animation loop
        this.autoRotate = false;
        this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60

        // Set to false to disable use of the keys
        this.enableKeys = true;

        // The four arrow keys
        this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };

        // Mouse buttons
        this.mouseButtons = { LEFT: THREE.MOUSE.LEFT, MIDDLE: THREE.MOUSE.MIDDLE, RIGHT: THREE.MOUSE.RIGHT };

        // for reset
        this.target0 = this.target.clone();
        this.position0 = this.object.position.clone();
        this.zoom0 = this.object.zoom;

        //
        // public methods
        //

        this.getPolarAngle = function () {

          return spherical.phi;

        };

        this.getAzimuthalAngle = function () {

          return spherical.theta;

        };

        this.saveState = function () {

          scope.target0.copy( scope.target );
          scope.position0.copy( scope.object.position );
          scope.zoom0 = scope.object.zoom;

        };

        this.reset = function () {

          scope.target.copy( scope.target0 );
          scope.object.position.copy( scope.position0 );
          scope.object.zoom = scope.zoom0;

          scope.object.updateProjectionMatrix();
          scope.dispatchEvent( changeEvent );

          scope.update();

          state = STATE.NONE;

        };

        // this method is exposed, but perhaps it would be better if we can make it private...
        this.update = function () {

          var offset = new THREE.Vector3();

          // so camera.up is the orbit axis
          var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
          var quatInverse = quat.clone().inverse();

          var lastPosition = new THREE.Vector3();
          var lastQuaternion = new THREE.Quaternion();

          return function update() {

            var position = scope.object.position;

            offset.copy( position ).sub( scope.target );

            // rotate offset to "y-axis-is-up" space
            offset.applyQuaternion( quat );

            // angle from z-axis around y-axis
            spherical.setFromVector3( offset );

            if ( scope.autoRotate && state === STATE.NONE ) {

              rotateLeft( getAutoRotationAngle() );

            }

            spherical.theta += sphericalDelta.theta;
            spherical.phi += sphericalDelta.phi;

            // restrict theta to be between desired limits
            spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );

            // restrict phi to be between desired limits
            spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );

            spherical.makeSafe();


            spherical.radius *= scale;

            // restrict radius to be between desired limits
            spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );

            // move target to panned location
            scope.target.add( panOffset );

            offset.setFromSpherical( spherical );

            // rotate offset back to "camera-up-vector-is-up" space
            offset.applyQuaternion( quatInverse );

            position.copy( scope.target ).add( offset );

            scope.object.lookAt( scope.target );

            if ( scope.enableDamping === true ) {

              sphericalDelta.theta *= ( 1 - scope.dampingFactor );
              sphericalDelta.phi *= ( 1 - scope.dampingFactor );

              panOffset.multiplyScalar( 1 - scope.dampingFactor );

            } else {

              sphericalDelta.set( 0, 0, 0 );

              panOffset.set( 0, 0, 0 );

            }

            scale = 1;

            // update condition is:
            // min(camera displacement, camera rotation in radians)^2 > EPS
            // using small-angle approximation cos(x/2) = 1 - x^2 / 8

            if ( zoomChanged ||
              lastPosition.distanceToSquared( scope.object.position ) > EPS ||
              8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {

              scope.dispatchEvent( changeEvent );

              lastPosition.copy( scope.object.position );
              lastQuaternion.copy( scope.object.quaternion );
              zoomChanged = false;

              return true;

            }

            return false;

          };

        }();

        this.dispose = function () {

          scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );
          scope.domElement.removeEventListener( 'mousedown', onMouseDown, false );
          scope.domElement.removeEventListener( 'wheel', onMouseWheel, false );

          scope.domElement.removeEventListener( 'touchstart', onTouchStart, false );
          scope.domElement.removeEventListener( 'touchend', onTouchEnd, false );
          scope.domElement.removeEventListener( 'touchmove', onTouchMove, false );

          document.removeEventListener( 'mousemove', onMouseMove, false );
          document.removeEventListener( 'mouseup', onMouseUp, false );

          window.removeEventListener( 'keydown', onKeyDown, false );

          //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?

        };

        //
        // internals
        //

        var scope = this;

        var changeEvent = { type: 'change' };
        var startEvent = { type: 'start' };
        var endEvent = { type: 'end' };

        var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 };

        var state = STATE.NONE;

        var EPS = 0.000001;

        // current position in spherical coordinates
        var spherical = new THREE.Spherical();
        var sphericalDelta = new THREE.Spherical();

        var scale = 1;
        var panOffset = new THREE.Vector3();
        var zoomChanged = false;

        var rotateStart = new THREE.Vector2();
        var rotateEnd = new THREE.Vector2();
        var rotateDelta = new THREE.Vector2();

        var panStart = new THREE.Vector2();
        var panEnd = new THREE.Vector2();
        var panDelta = new THREE.Vector2();

        var dollyStart = new THREE.Vector2();
        var dollyEnd = new THREE.Vector2();
        var dollyDelta = new THREE.Vector2();

        function getAutoRotationAngle() {

          return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;

        }

        function getZoomScale() {

          return Math.pow( 0.95, scope.zoomSpeed );

        }

        function rotateLeft( angle ) {

          sphericalDelta.theta -= angle;

        }

        function rotateUp( angle ) {

          sphericalDelta.phi -= angle;

        }

        var panLeft = function () {

          var v = new THREE.Vector3();

          return function panLeft( distance, objectMatrix ) {

            v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
            v.multiplyScalar( - distance );

            panOffset.add( v );

          };

        }();

        var panUp = function () {

          var v = new THREE.Vector3();

          return function panUp( distance, objectMatrix ) {

            if ( scope.screenSpacePanning === true ) {

              v.setFromMatrixColumn( objectMatrix, 1 );

            } else {

              v.setFromMatrixColumn( objectMatrix, 0 );
              v.crossVectors( scope.object.up, v );

            }

            v.multiplyScalar( distance );

            panOffset.add( v );

          };

        }();

        // deltaX and deltaY are in pixels; right and down are positive
        var pan = function () {

          var offset = new THREE.Vector3();

          return function pan( deltaX, deltaY ) {

            var element = scope.domElement === document ? scope.domElement.body : scope.domElement;

            if ( scope.object.isPerspectiveCamera ) {

              // perspective
              var position = scope.object.position;
              offset.copy( position ).sub( scope.target );
              var targetDistance = offset.length();

              // half of the fov is center to top of screen
              targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );

              // we use only clientHeight here so aspect ratio does not distort speed
              panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
              panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );

            } else if ( scope.object.isOrthographicCamera ) {

              // orthographic
              panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
              panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );

            } else {

              // camera neither orthographic nor perspective
              console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
              scope.enablePan = false;

            }

          };

        }();

        function dollyIn( dollyScale ) {

          if ( scope.object.isPerspectiveCamera ) {

            scale /= dollyScale;

          } else if ( scope.object.isOrthographicCamera ) {

            scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
            scope.object.updateProjectionMatrix();
            zoomChanged = true;

          } else {

            console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
            scope.enableZoom = false;

          }

        }

        function dollyOut( dollyScale ) {

          if ( scope.object.isPerspectiveCamera ) {

            scale *= dollyScale;

          } else if ( scope.object.isOrthographicCamera ) {

            scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
            scope.object.updateProjectionMatrix();
            zoomChanged = true;

          } else {

            console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
            scope.enableZoom = false;

          }

        }

        //
        // event callbacks - update the object state
        //

        function handleMouseDownRotate( event ) {

          //console.log( 'handleMouseDownRotate' );

          rotateStart.set( event.clientX, event.clientY );

        }

        function handleMouseDownDolly( event ) {

          //console.log( 'handleMouseDownDolly' );

          dollyStart.set( event.clientX, event.clientY );

        }

        function handleMouseDownPan( event ) {

          //console.log( 'handleMouseDownPan' );

          panStart.set( event.clientX, event.clientY );

        }

        function handleMouseMoveRotate( event ) {

          //console.log( 'handleMouseMoveRotate' );

          rotateEnd.set( event.clientX, event.clientY );

          rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );

          var element = scope.domElement === document ? scope.domElement.body : scope.domElement;

          rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height

          rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );

          rotateStart.copy( rotateEnd );

          scope.update();

        }

        function handleMouseMoveDolly( event ) {

          //console.log( 'handleMouseMoveDolly' );

          dollyEnd.set( event.clientX, event.clientY );

          dollyDelta.subVectors( dollyEnd, dollyStart );

          if ( dollyDelta.y > 0 ) {

            dollyIn( getZoomScale() );

          } else if ( dollyDelta.y < 0 ) {

            dollyOut( getZoomScale() );

          }

          dollyStart.copy( dollyEnd );

          scope.update();

        }

        function handleMouseMovePan( event ) {

          //console.log( 'handleMouseMovePan' );

          panEnd.set( event.clientX, event.clientY );

          panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );

          pan( panDelta.x, panDelta.y );

          panStart.copy( panEnd );

          scope.update();

        }

        function handleMouseUp( event ) {

          // console.log( 'handleMouseUp' );

        }

        function handleMouseWheel( event ) {

          // console.log( 'handleMouseWheel' );

          if ( event.deltaY < 0 ) {

            dollyOut( getZoomScale() );

          } else if ( event.deltaY > 0 ) {

            dollyIn( getZoomScale() );

          }

          scope.update();

        }

        function handleKeyDown( event ) {

          // console.log( 'handleKeyDown' );

          var needsUpdate = false;

          switch ( event.keyCode ) {

            case scope.keys.UP:
              pan( 0, scope.keyPanSpeed );
              needsUpdate = true;
              break;

            case scope.keys.BOTTOM:
              pan( 0, - scope.keyPanSpeed );
              needsUpdate = true;
              break;

            case scope.keys.LEFT:
              pan( scope.keyPanSpeed, 0 );
              needsUpdate = true;
              break;

            case scope.keys.RIGHT:
              pan( - scope.keyPanSpeed, 0 );
              needsUpdate = true;
              break;

          }

          if ( needsUpdate ) {

            // prevent the browser from scrolling on cursor keys
            event.preventDefault();

            scope.update();

          }


        }

        function handleTouchStartRotate( event ) {

          //console.log( 'handleTouchStartRotate' );

          rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );

        }

        function handleTouchStartDollyPan( event ) {

          //console.log( 'handleTouchStartDollyPan' );

          if ( scope.enableZoom ) {

            var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
            var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;

            var distance = Math.sqrt( dx * dx + dy * dy );

            dollyStart.set( 0, distance );

          }

          if ( scope.enablePan ) {

            var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX );
            var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY );

            panStart.set( x, y );

          }

        }

        function handleTouchMoveRotate( event ) {

          //console.log( 'handleTouchMoveRotate' );

          rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );

          rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );

          var element = scope.domElement === document ? scope.domElement.body : scope.domElement;

          rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height

          rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );

          rotateStart.copy( rotateEnd );

          scope.update();

        }

        function handleTouchMoveDollyPan( event ) {

          //console.log( 'handleTouchMoveDollyPan' );

          if ( scope.enableZoom ) {

            var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
            var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;

            var distance = Math.sqrt( dx * dx + dy * dy );

            dollyEnd.set( 0, distance );

            dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );

            dollyIn( dollyDelta.y );

            dollyStart.copy( dollyEnd );

          }

          if ( scope.enablePan ) {

            var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX );
            var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY );

            panEnd.set( x, y );

            panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );

            pan( panDelta.x, panDelta.y );

            panStart.copy( panEnd );

          }

          scope.update();

        }

        function handleTouchEnd( event ) {

          //console.log( 'handleTouchEnd' );

        }

        //
        // event handlers - FSM: listen for events and reset state
        //

        function onMouseDown( event ) {

          if ( scope.enabled === false ) return;

          // Prevent the browser from scrolling.

          event.preventDefault();

          // Manually set the focus since calling preventDefault above
          // prevents the browser from setting it automatically.

          scope.domElement.focus ? scope.domElement.focus() : window.focus();

          switch ( event.button ) {

            case scope.mouseButtons.LEFT:

              if ( event.ctrlKey || event.metaKey || event.shiftKey ) {

                if ( scope.enablePan === false ) return;

                handleMouseDownPan( event );

                state = STATE.PAN;

              } else {

                if ( scope.enableRotate === false ) return;

                handleMouseDownRotate( event );

                state = STATE.ROTATE;

              }

              break;

            case scope.mouseButtons.MIDDLE:

              if ( scope.enableZoom === false ) return;

              handleMouseDownDolly( event );

              state = STATE.DOLLY;

              break;

            case scope.mouseButtons.RIGHT:

              if ( scope.enablePan === false ) return;

              handleMouseDownPan( event );

              state = STATE.PAN;

              break;

          }

          if ( state !== STATE.NONE ) {

            document.addEventListener( 'mousemove', onMouseMove, false );
            document.addEventListener( 'mouseup', onMouseUp, false );

            scope.dispatchEvent( startEvent );

          }

        }

        function onMouseMove( event ) {

          if ( scope.enabled === false ) return;

          event.preventDefault();

          switch ( state ) {

            case STATE.ROTATE:

              if ( scope.enableRotate === false ) return;

              handleMouseMoveRotate( event );

              break;

            case STATE.DOLLY:

              if ( scope.enableZoom === false ) return;

              handleMouseMoveDolly( event );

              break;

            case STATE.PAN:

              if ( scope.enablePan === false ) return;

              handleMouseMovePan( event );

              break;

          }

        }

        function onMouseUp( event ) {

          if ( scope.enabled === false ) return;

          handleMouseUp( event );

          document.removeEventListener( 'mousemove', onMouseMove, false );
          document.removeEventListener( 'mouseup', onMouseUp, false );

          scope.dispatchEvent( endEvent );

          state = STATE.NONE;

        }

        function onMouseWheel( event ) {

          if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;

          event.preventDefault();
          event.stopPropagation();

          scope.dispatchEvent( startEvent );

          handleMouseWheel( event );

          scope.dispatchEvent( endEvent );

        }

        function onKeyDown( event ) {

          if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;

          handleKeyDown( event );

        }

        function onTouchStart( event ) {

          if ( scope.enabled === false ) return;

          event.preventDefault();

          switch ( event.touches.length ) {

            case 1:	// one-fingered touch: rotate

              if ( scope.enableRotate === false ) return;

              handleTouchStartRotate( event );

              state = STATE.TOUCH_ROTATE;

              break;

            case 2:	// two-fingered touch: dolly-pan

              if ( scope.enableZoom === false && scope.enablePan === false ) return;

              handleTouchStartDollyPan( event );

              state = STATE.TOUCH_DOLLY_PAN;

              break;

            default:

              state = STATE.NONE;

          }

          if ( state !== STATE.NONE ) {

            scope.dispatchEvent( startEvent );

          }

        }

        function onTouchMove( event ) {

          if ( scope.enabled === false ) return;

          event.preventDefault();
          event.stopPropagation();

          switch ( event.touches.length ) {

            case 1: // one-fingered touch: rotate

              if ( scope.enableRotate === false ) return;
              if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?

              handleTouchMoveRotate( event );

              break;

            case 2: // two-fingered touch: dolly-pan

              if ( scope.enableZoom === false && scope.enablePan === false ) return;
              if ( state !== STATE.TOUCH_DOLLY_PAN ) return; // is this needed?

              handleTouchMoveDollyPan( event );

              break;

            default:

              state = STATE.NONE;

          }

        }

        function onTouchEnd( event ) {

          if ( scope.enabled === false ) return;

          handleTouchEnd( event );

          scope.dispatchEvent( endEvent );

          state = STATE.NONE;

        }

        function onContextMenu( event ) {

          if ( scope.enabled === false ) return;

          event.preventDefault();

        }

        //

        scope.domElement.addEventListener( 'contextmenu', onContextMenu, false );

        scope.domElement.addEventListener( 'mousedown', onMouseDown, false );
        scope.domElement.addEventListener( 'wheel', onMouseWheel, false );

        scope.domElement.addEventListener( 'touchstart', onTouchStart, false );
        scope.domElement.addEventListener( 'touchend', onTouchEnd, false );
        scope.domElement.addEventListener( 'touchmove', onTouchMove, false );

        window.addEventListener( 'keydown', onKeyDown, false );

        // force an update at start

        this.update();

      };

      THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
      THREE.OrbitControls.prototype.constructor = THREE.OrbitControls;

      Object.defineProperties( THREE.OrbitControls.prototype, {

        center: {

          get: function () {

            console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
            return this.target;

          }

        },

        // backward compatibility

        noZoom: {

          get: function () {

            console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
            return ! this.enableZoom;

          },

          set: function ( value ) {

            console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
            this.enableZoom = ! value;

          }

        },

        noRotate: {

          get: function () {

            console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
            return ! this.enableRotate;

          },

          set: function ( value ) {

            console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
            this.enableRotate = ! value;

          }

        },

        noPan: {

          get: function () {

            console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
            return ! this.enablePan;

          },

          set: function ( value ) {

            console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
            this.enablePan = ! value;

          }

        },

        noKeys: {

          get: function () {

            console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
            return ! this.enableKeys;

          },

          set: function ( value ) {

            console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
            this.enableKeys = ! value;

          }

        },

        staticMoving: {

          get: function () {

            console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
            return ! this.enableDamping;

          },

          set: function ( value ) {

            console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
            this.enableDamping = ! value;

          }

        },

        dynamicDampingFactor: {

          get: function () {

            console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
            return this.dampingFactor;

          },

          set: function ( value ) {

            console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
            this.dampingFactor = value;

          }

        }

      } )*/
    },
    mounted() {
      this.init()
      this.animate()
    },
    methods: {
      init() {
        this.canvas = document.getElementById('c')
        console.info('Canvas is: ', this.canvas)

        const geometries = [
          new THREE.BoxBufferGeometry(1, 1, 1),
          new THREE.SphereBufferGeometry(0.5, 12, 8),
          new THREE.DodecahedronBufferGeometry(0.5),
          new THREE.CylinderBufferGeometry(0.5, 0.5, 1, 12)
        ]

        // const template = document.getElementById('template').text
        const content = document.getElementById('content')
        console.info('Content is: ', content)

        for (let i = 0; i < 40; i++) {
          const scene = new THREE.Scene()
          // make a list item
          const element = document.createElement('div')
          element.className = 'list-item'
          // element.innerHTML = template.replace('$', i + 1)
          element.innerHTML = `
            			<div class="scene"></div>
			            <div class="description">Scene ${i + 1}</div>
          `

          scene.userData.element = element.querySelector('.scene')
          content.appendChild(element)

          const camera = new THREE.PerspectiveCamera(50, 1, 1, 10)
          camera.position.z = 2
          scene.userData.camera = camera

          // const controls = new THREE.OrbitControls(scene.userData.camera, scene.userData.element)
          // controls.minDistance = 2
          // controls.maxDistance = 5
          // controls.enablePan = false
          // controls.enableZoom = false
          // scene.userData.controls = controls

          const geometry = geometries[geometries.length * Math.random() | 0]
          const material = new THREE.MeshStandardMaterial({
            color: new THREE.Color().setHSL(Math.random(), 1, 0.75),
            roughness: 0.5,
            metalness: 0,
            flatShading: true
          })
          scene.add(new THREE.Mesh(geometry, material))
          scene.add(new THREE.HemisphereLight(0xaaaaaa, 0x444444))
          const light = new THREE.DirectionalLight(0xffffff, 0.5)
          light.position.set(1, 1, 1)
          scene.add(light)
          this.scenes.push(scene)
        }

        this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas, antialias: true })
        this.renderer.setClearColor(0xffffff, 1)
        this.renderer.setPixelRatio(window.devicePixelRatio)

        this.render()
      },
      updateSize() {
        const width = this.canvas.clientWidth
        const height = this.canvas.clientHeight
        if (this.canvas.width !== width || this.canvas.height !== height) {
          this.renderer.setSize(width, height, false)
        }
      },
      animate() {
        this.render()
        requestAnimationFrame(this.animate)
      },
      render() {
        this.updateSize()

        this.canvas.style.transform = `translateY(${window.scrollY}px)`

        this.renderer.setClearColor(0xffffff)
        this.renderer.setScissorTest(false)
        this.renderer.clear()

        this.renderer.setClearColor(0xe0e0e0)
        this.renderer.setScissorTest(true)

        this.scenes.forEach(scene => {
          // so something moves
          scene.children[0].rotation.y = Date.now() * 0.001
          // get the element that is a place holder for where we want to
          // draw the scene
          const element = scene.userData.element
          // get its position relative to the page's viewport
          const rect = element.getBoundingClientRect()
          // check if it's offscreen. If so skip it
          if (rect.bottom < 0 || rect.top > this.renderer.domElement.clientHeight ||
            rect.right < 0 || rect.left > this.renderer.domElement.clientWidth ) {
            return // it's off screen
          }
          // set the viewport
          const width = rect.right - rect.left
          const height = rect.bottom - rect.top
          const left = rect.left
          const bottom = this.renderer.domElement.clientHeight - rect.bottom
          this.renderer.setViewport(left, bottom, width, height)
          this.renderer.setScissor(left, bottom, width, height)
          const camera = scene.userData.camera
          //camera.aspect = width / height // not changing in this example
          //camera.updateProjectionMatrix()
          //scene.userData.controls.update()
          this.renderer.render(scene, camera)
        })
      }
    }
  }
</script>
<style>
  * {
    box-sizing: border-box;
    -moz-box-sizing: border-box;
  }
  body {
    color: #000;
    font-family:Monospace;
    font-size:13px;
    background-color: #fff;
    margin: 0;
  }
  #info {
    position: absolute;
    top: 0; width: 100%;
    padding: 5px;
    text-align:center;
  }
  #content {
    position: absolute;
    top: 0; width: 100%;
    z-index: 1;
    padding: 3em 0 0 0;
  }
  a {
    color: #0080ff;
  }
  #c {
    position: absolute;
    left: 0;
    width: 100%;
    height: 100%;
  }
  .list-item {
    display: inline-block;
    margin: 1em;
    padding: 1em;
    box-shadow: 1px 2px 4px 0px rgba(0,0,0,0.25);
  }
  .list-item .scene {
    width: 200px;
    height: 200px;
  }
  .list-item .description {
    color: #888;
    font-family: sans-serif;
    font-size: large;
    width: 200px;
    margin-top: 1.5em;
  }
</style>
